﻿using Architecture.Domain.Dto.LeaveDto;
using Architecture.Repository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Architecture.Domain.Service.LeaveServices
{
    /// <summary>
    /// 请假服务
    /// </summary>
    public class LeaveService : ILeaveService
    {
        /// <summary>
        /// 请假信息仓储
        /// </summary>
        protected readonly ILeaveRepository _leaveRepository;

        /// <summary>
        /// 用户信息仓储
        /// </summary>
        protected readonly IUserInfoRepository _userInfoRepository;

        /// <summary>
        /// 省信息仓储
        /// </summary>
        protected readonly IProvinceRepository _provinceRepository;

        /// <summary>
        /// 市信息仓储
        /// </summary>
        protected readonly ICityRepository _cityRepository;

        /// <summary>
        /// 县信息仓储
        /// </summary>
        protected readonly ICountryRepository _courierRepository;

        /// <summary>
        ///  用户信息角色服务
        /// </summary>
        protected readonly IUserInfoRoleRepository _userInfoRoleRepository;

        /// <summary>
        /// 角色仓储
        /// </summary>
        protected readonly IRoleRepository _roleRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userInfoRepository">用户信息仓储</param>
        /// <param name="provinceRepository">省信息仓储</param>
        /// <param name="cityRepository">市信息仓储</param>
        /// <param name="courierRepository">县信息仓储</param>
        /// <param name="roleRepository">角色仓储</param>
        /// <param name="userInfoRoleRepository">用户信息角色仓储</param>
        /// <param name="leaveRepository">请假信息仓储</param>
        public LeaveService(IUserInfoRepository userInfoRepository, IProvinceRepository provinceRepository, ICityRepository cityRepository, ICountryRepository courierRepository, IRoleRepository roleRepository, IUserInfoRoleRepository userInfoRoleRepository, ILeaveRepository leaveRepository)
        {
            _userInfoRepository = userInfoRepository;
            _provinceRepository = provinceRepository;
            _cityRepository = cityRepository;
            _courierRepository = courierRepository;
            _roleRepository = roleRepository;
            _userInfoRoleRepository = userInfoRoleRepository;
            _leaveRepository = leaveRepository;
        }

        /// <summary>
        /// 添加请假信息
        /// </summary>
        /// <param name="requestForLeave">请假实体</param>
        /// <returns>返回受影响的行数</returns>
        public async Task<int> AddLeave(RequestForLeave requestForLeave)
        {
            requestForLeave.CreatedBy = "";
            requestForLeave.CreatedDate = DateTime.Now;
            var result = await _leaveRepository.AddAsync(requestForLeave);
            return result;
        }

        /// <summary>
        /// 获取角色部分信息
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>返回角色部分信息</returns>
        public async Task<List<LeaveSeachDto>> GetLeave(int userId)
        {
            var list = (from a in await _userInfoRepository.GetAllAsync()
                       join b in await _userInfoRoleRepository.GetAllAsync()
                       on a.UserId equals b.UserId
                       join c in await _roleRepository.GetAllAsync()
                       on b.RoleId equals c.RoleId
                       where a.UserId == userId && !a.IsDeleted && !b.IsDeleted && !c.IsDeleted
                       select new LeaveSeachDto
                       {
                           UserName = a.UserName,
                           DepartmentId = a.DepartmentId,
                           RoleId = b.RoleId,
                           RoleName = c.RoleName
                       }).ToList();
            return list;
        }

        /// <summary>
        /// 反填角色信息
        /// </summary>
        /// <param name="userId">角色ID</param>
        /// <returns>返回反填的角色信息</returns>
        public async Task<UserInfo> GetModelUserInfo(int userId)
        {
            return await _userInfoRepository.GetModelAsync(userId);
        }

        /// <summary>
        /// 通过部门ID获取用户信息
        /// </summary>
        /// <param name="departmentId">部门ID</param>
        /// <returns>返回用户信息</returns>
        public async Task<List<UserInfoDepartmentDto>> GetUserInfoDepartment(int departmentId)
        {
            var list = from a in await _userInfoRepository.GetAllAsync()
                       join b in await _userInfoRoleRepository.GetAllAsync()
                       on a.UserId equals b.UserId
                       join c in await _roleRepository.GetAllAsync()
                       on b.RoleId equals c.RoleId
                       where a.DepartmentId == departmentId && c.IsDefault==true && !a.IsDeleted && !b.IsDeleted && !c.IsDeleted
                       select new UserInfoDepartmentDto
                       {
                           UserId = a.UserId,
                           UserName = a.UserName
                       };
            return list.Distinct().ToList();
        }

        /// <summary>
        /// 获取请假列表
        /// </summary>
        /// <param name="PageIndex">当前页</param>
        /// <param name="PageSize">页容量</param>
        /// <param name="UserName">用户名</param>
        /// <param name="ToExamine">审核状态</param>
        /// <returns>返回请假列表</returns>
        public async Task<LeaveListDto<GetInfoDto>> GetLeaveList(int UserId, int PageIndex, int PageSize, string? UserName, bool? ToExamine)
        {
            var paging = new LeaveListDto<GetInfoDto>();

            var list = (from a in await _userInfoRepository.GetAllAsync()
                       join b in await _leaveRepository.GetAllAsync()          
                       on a.DepartmentId equals b.DepartmentId
                       where a.UserId==UserId && !a.IsDeleted && !b.IsDeleted /*&& !c.IsDeleted && !d.IsDeleted */
                       select new GetInfoDto
                       {
                           UserId = a.UserId,
                           LeaveId = b.LeaveId,
                           UserName = b.UserName,   
                           DepartmentId = b.DepartmentId,
                           LeaveType = b.LeaveType,
                           LeaveStartTime = b.LeaveStartTime,
                           LeaveEndTime = b.LeaveEndTime,
                           TotalWorkTime = b.TotalWorkTime,
                           RegistrationTime = b.RegistrationTime,
                           SubjectMatter = b.SubjectMatter,
                           DepartmentLeader = b.DepartmentLeader,
                           ToExamine = b.ToExamine,
                           CreatedDate = b.CreatedDate,
                           //IsDefault=d.IsDefault
                           
                       }).Distinct().ToList(); 

            list = list.Where(x => x.UserId == UserId).ToList();

            if (!string.IsNullOrEmpty(UserName))
            {
                list = list.Where(x => x.UserName.Contains(UserName)).ToList();
            }

            if (ToExamine!=null)
            {
                list=list.Where(x=>x.ToExamine==ToExamine).ToList();
            }

            paging.TotalCount = list.Count();
            paging.PageCount = (int)Math.Ceiling(list.Count() * 1.0 / PageSize);
            paging.list=list.OrderBy(x=>x.CreatedDate).Skip((PageIndex-1)*PageSize).Take(PageSize).ToList();
            return paging;
        }

        /// <summary>
        /// 反填请假信息
        /// </summary>
        /// <param name="leaveId">请假ID</param>
        /// <returns>反填请假信息</returns>
        public async Task<RequestForLeave> ReverseLeave(int leaveId)
        {
            var res = await _leaveRepository.GetModelAsync(leaveId);
            return res;
        }

        /// <summary>
        /// 审批
        /// </summary>
        /// <param name="leaveId">请假ID</param>
        /// <param name="toExamine">审批字段</param>
        /// <returns>返回受影响的行数</returns>
        public async Task<int> ToExamineLeave(int leaveId,bool toExamine)
        {
            var res = await _leaveRepository.GetModelAsync(leaveId);
            res.ToExamine=toExamine;
            return await _leaveRepository.UpdateAsync(res);
        }

        /// <summary>
        /// 修改请假信息
        /// </summary>
        /// <param name="requestForLeave">请假模型</param>
        /// <returns>返回受影响的行数</returns>
        public async Task<int> UpdateLeave(RequestForLeave requestForLeave)
        {
            requestForLeave.UpdatedBy = "";
            requestForLeave.UpdatedDate = DateTime.Now;
            return await _leaveRepository.UpdateAsync(requestForLeave);
        }

        /// <summary>
        /// 删除请假信息
        /// </summary>
        /// <param name="leaveId">请假ID</param>
        /// <returns>返回受影响的行数</returns>
        public async Task<int> DeletedLeave(int leaveId)
        {
            var res = await _leaveRepository.GetModelAsync(leaveId);
            res.DeletedBy = "";
            res.DeletedDate = DateTime.Now;
            res.IsDeleted = true;
            return await _leaveRepository.UpdateAsync(res);
        }
    }
}
